<?php

namespace app\middleware;

use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
use app\model\OperationLogModel;
use app\model\UsersModel;
use support\Db;
use support\Redis;

class OperationLog implements MiddlewareInterface
{
    public function process(Request $request, callable $handler): Response
    {
        $startTime = microtime(true);
        
        // 执行请求
        $response = $handler($request);
        
        $endTime = microtime(true);
        $duration = round(($endTime - $startTime) * 1000, 2); // 毫秒
        
        // 异步记录日志，避免影响响应速度
        $this->logOperation($request, $response, $duration);
        
        return $response;
    }
    
    /**
     * 记录操作日志
     */
    private function logOperation(Request $request, Response $response, float $duration)
    {
        try {
            // 获取用户信息
            $userInfo = $this->getUserInfo($request);
            
            // 获取请求信息
            $method = $request->method();
            $uri = $request->uri();
            $ip = $request->getRealIp();
            $userAgent = $request->header('user-agent', '');
            
            // 获取控制器和方法名
            $controller = $request->controller ?? '';
            $action = $request->action ?? '';
            
            // 构建操作描述
            $description = $this->buildDescription($controller, $action, $method, $userInfo['type']);
            
            // 获取请求参数（过滤敏感信息）
            $requestData = $this->filterSensitiveData($request->all());
            
            // 获取响应状态码
            $statusCode = $response->getStatusCode();
            
            // 判断操作结果
            $responseBody = $response->rawBody();
            $responseData = json_decode($responseBody, true);
            $isSuccess = $statusCode === 200 && (isset($responseData['code']) ? $responseData['code'] === 200 : true);
            
            // 记录到数据库
            OperationLogModel::create([
                'admin_id' => $userInfo['type'] === 'admin' ? $userInfo['id'] : null,
                'user_type' => $userInfo['type'],
                'user_id' => $userInfo['type'] === 'user' ? $userInfo['id'] : null,
                'method' => $method,
                'uri' => $uri,
                'controller' => $this->getControllerName($controller),
                'action' => $action,
                'description' => $description,
                'request_data' => json_encode($requestData, JSON_UNESCAPED_UNICODE),
                'response_code' => $statusCode,
                'is_success' => $isSuccess ? 1 : 0,
                'duration' => $duration,
                'ip' => $ip,
                'user_agent' => $userAgent,
                'created_at' => date('Y-m-d H:i:s')
            ]);
        } catch (\Exception $e) {
            // 记录日志失败不应该影响正常业务
            error_log('操作日志记录失败: ' . $e->getMessage());
        }
    }
    
    /**
     * 获取用户信息
     */
    private function getUserInfo(Request $request): array
    {
        // 默认返回值
        $defaultInfo = ['type' => 'guest', 'id' => null];
        
        // 检查管理员用户
        $adminId = $request->admin_id ?? null;
        if ($adminId) {
            return ['type' => 'admin', 'id' => $adminId];
        }
        
        // 检查普通用户token
        $token = $request->header('authorization');
        if ($token) {
            $userId = Redis::get($token);
            if ($userId) {
                // 验证用户是否存在
                $user = UsersModel::find($userId);
                if ($user) {
                    return ['type' => 'user', 'id' => $userId];
                }
            }
        }
        
        return $defaultInfo;
    }
    
    /**
     * 构建操作描述
     */
    private function buildDescription(string $controller, string $action, string $method, string $userType = 'guest'): string
    {
        $controllerName = $this->getControllerName($controller);
        
        $descriptions = [
            'Auth' => [
                'login' => '管理员登录',
                'logout' => '管理员退出',
                'getInfo' => '获取管理员信息',
                'getMenus' => '获取管理员菜单',
                'getAllMenus' => '获取所有菜单',
                'saveMenus' => '保存菜单',
                'deleteMenus' => '删除菜单',
                'getRoles' => '获取角色列表',
                'saveRole' => '保存角色',
                'deleteRole' => '删除角色',
                'getUsers' => '获取用户列表',
                'saveUser' => '保存用户',
                'deleteUser' => '删除用户'
            ],
            'User' => [
                'login' => '用户登录',
                'wechatLogin' => '微信登录',
                'getUserInfo' => '获取用户信息',
                'saveUser' => '保存用户信息',
                'deleteUser' => '删除用户',
                'toggleUserStatus' => '切换用户状态',
                'getUsers' => '获取用户列表'
            ]
        ];
        
        if (isset($descriptions[$controllerName][$action])) {
            $desc = $descriptions[$controllerName][$action];
            // 根据用户类型调整描述
            if ($userType === 'user' && $controllerName === 'User') {
                $desc = str_replace('用户', '个人', $desc);
            }
            return $desc;
        }
        
        // 默认描述
        $userTypeText = $userType === 'admin' ? '管理员' : ($userType === 'user' ? '用户' : '访客');
        return "{$userTypeText} {$method} {$controllerName}/{$action}";
    }
    
    /**
     * 获取控制器名称
     */
    private function getControllerName(string $controllerClass): string
    {
        if (empty($controllerClass)) {
            return '';
        }
        
        $className = class_basename($controllerClass);
        return str_replace('Controller', '', $className);
    }
    
    /**
     * 过滤敏感数据
     */
    private function filterSensitiveData(array $data): array
    {
        $sensitiveFields = ['password', 'password_confirmation', 'token', 'authorization'];
        
        foreach ($sensitiveFields as $field) {
            if (isset($data[$field])) {
                $data[$field] = '***';
            }
        }
        
        return $data;
    }
}